using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using Microsoft.Xna.Framework.Media;
using System.IO.IsolatedStorage;
using System.IO;
using System.Text;
using Mogade.WindowsPhone;
using Mogade;

namespace rocketjump
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class JumpGame : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        static public Camera primary_camera;

        MainMenu mainMenu;
        public static IMogadeClient mogade { get; private set; }

        static public bool jumpOver = false;
        static public bool gameReady = true;
        static public bool endMenuVisible = false;

        private bool fanfarePlayed = false;

        bool inMenu;
        bool inGame;
#if WINDOWS
        MouseState prevMouseState;
#endif

        List<BackgroundSprite> backgroundLayer;
        List<Sprite> objectLayer;
        List<Sprite> UILayer;

        SpriteFont debugFont;
        SpriteFont uiFont;
        SpriteFont uiFontLarge;

        Texture2D bg;

        PlayerSprite player;

        List<Texture2D> particles;
        Texture2D debugParticle;
        Texture2D successsign;
        Texture2D failsign;
        Texture2D failsign2;
        Texture2D facesign;
        Texture2D sammydude;
        Texture2D tree;
        Texture2D mountain;
        Texture2D sun;
        Texture2D galaxy1;
        Texture2D galaxy2;
        Texture2D asteroid01;
        Texture2D asteroid02;
        Texture2D asteroid03;
        Texture2D moon;
        Texture2D cloud;
        Texture2D textBox;

        ParticleEngine particleEngine;
        ParticleEngine snowEmitter;
        int successfulTricks = 0;
        public int trickErrors = 0;
        int counter = 0;

        int cloudVelocityModifier;
        Texture2D snowTile;

        float timeToShowEarly = 0f;
        float timeToShowFail = 0;
        float timeToShowScore = 0f;
        float timeTillNextTrick = 2500f;
        float difficulty = -1000;   //time to tap
        int lastScoreGained = 0;
        float angleBonus = 0;

        Random random;
        static int score = 0;
        bool vibration = false;

        static int hiscore = 0;
        static int onlineHighScore = 0;
        static string rankText =  "Rank: Loading";

        float distance_travelled = 0;

        int nextTapCount = 1;

        static int gamePlayed = 0;

        float totalElapsedEnd = 0;

        public JumpGame()
        {
            graphics = new GraphicsDeviceManager(this);
            graphics.IsFullScreen = true;
            Content.RootDirectory = "Content";

            // Frame rate is 30 fps by default for Windows Phone.
            TargetElapsedTime = TimeSpan.FromTicks(333333);

            // Extend battery life under lock.
            InactiveSleepTime = TimeSpan.FromSeconds(1);

            backgroundLayer = new List<BackgroundSprite>();
            objectLayer = new List<Sprite>();
            UILayer = new List<Sprite>();

            particles = new List<Texture2D>();

            graphics.PreferredBackBufferWidth = 800;
            graphics.PreferredBackBufferHeight = 480;
#if WINDOWS
            graphics.IsFullScreen = false;
#endif
            this.IsMouseVisible = true;

            inMenu = true;
            inGame = false;

            random = new Random();

            mainMenu = new MainMenu();

            string secret = ";PdGfFkbBa=Mfrq;jrOcxtp3pdojefjos"; //todo: obsuscate this key
            string xx = "_^DHJTQ`bBp";
            string yy = "vqjy_oh7;xo";


            //configure
            MogadeConfiguration.Configuration(c => c.UsingUniqueIdStrategy(UniqueIdStrategy.UserId));
            //intialize (thread-safe, so keep one around)
            mogade = MogadeClient.Initialize("4f296773563d8a69ff000017", xx.Substring(1) + secret.Substring(10, 6) + yy.Substring(0, 10));

            mogade.LogApplicationStart();
            mogade.GetPlayerScore("4f3e2ad4563d8a2c6e000024", LeaderboardScope.Overall, mogade.GetUniqueIdentifier().Substring(0, 8), ScoreResponseHandler);

            cloudVelocityModifier = 70;
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            base.Initialize();
            SoundHelper.PlayMusic("sounds\\clip7");
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            GraphicsHelper.Initialize(this, spriteBatch);
            SoundHelper.Initialize(this);

            debugFont = Content.Load<SpriteFont>("fonts/Debug");
            uiFont = Content.Load<SpriteFont>("fonts/UIFont");
            uiFontLarge = Content.Load<SpriteFont>("fonts/uiFontLarge");

            debugParticle = Content.Load<Texture2D>("graphics/effects/debugParticle");
            particles.Add(debugParticle);
/*            debugParticle = Content.Load<Texture2D>("graphics/effects/snowflake02");
            particles.Add(debugParticle);
            debugParticle = Content.Load<Texture2D>("graphics/effects/snowflake03");
            particles.Add(debugParticle);*/
            snowEmitter = new ParticleEngine(particles, new Vector2(0, 0), 50, 0.3f, 10, 2);
            snowEmitter.Start();

            tree = Content.Load<Texture2D>("graphics/background/tree");
            mountain = Content.Load<Texture2D>("graphics/background/mountains_tiled");
            successsign = Content.Load<Texture2D>("graphics/objects/trick-good");
            facesign = Content.Load<Texture2D>("graphics/objects/trick-good2");
            failsign = Content.Load<Texture2D>("graphics/objects/trick-bad");
            failsign2 = Content.Load<Texture2D>("graphics/objects/trick-bad2");
            sammydude = Content.Load<Texture2D>("graphics/objects/sammydude2");
            sun = Content.Load<Texture2D>("graphics/background/sun");
            galaxy1 = Content.Load<Texture2D>("graphics/background/galaxy01");
            galaxy2 = Content.Load<Texture2D>("graphics/background/galaxy02");
            asteroid01 = Content.Load<Texture2D>("graphics/background/asteroid01");
            asteroid02 = Content.Load<Texture2D>("graphics/background/asteroid02");
            asteroid03 = Content.Load<Texture2D>("graphics/background/asteroid03");
            moon = Content.Load<Texture2D>("graphics/background/moon");
            textBox = Content.Load<Texture2D>("graphics/objects/textbox");

            primary_camera = new Camera();
            LoadLevel();
            mainMenu.loadContent(Content);
            player = new PlayerSprite();            
            // TODO: use this.Content to load your game content here
        }

        private void LoadUI()
        {
            UILayer.Clear();

        }

        private void LoadLevel()
        {
            backgroundLayer.Clear();
            objectLayer.Clear();
            Random rand = new Random();
            bg = GraphicsHelper.LoadTexture("graphics\\background\\bg-new");

            int Item_count = rand.Next(8, 15);
            for (int i = 1; i < Item_count; i++)
            {
                BackgroundSprite cloud = new BackgroundSprite();
                cloud.position.X = rand.Next(0,1200);
                cloud.position.Y = rand.Next(-480,200);
                cloud.parallex = i * 2 + 30;
                //Scale?
                switch (rand.Next(1, 8))
                {
                    case 1:
                        cloud.SetTexture("graphics\\background\\cloud");
                        break;
                    case 2:
                        cloud.SetTexture("graphics\\background\\cloud1");
                        break;
                    case 3:
                        cloud.SetTexture("graphics\\background\\cloud2");
                        break;
                    case 4:
                        cloud.SetTexture("graphics\\background\\cloud3");
                        break;
                    case 5:
                    case 6:
                        cloud.SetTexture("graphics\\background\\seagulls");
                        break;
                    case 7:
                        cloud.SetTexture("graphics\\background\\plane");
                        break;
                }
                backgroundLayer.Add(cloud);
            }
            /*
            for (int i = 1; i < 10; i++)
            {
                BackgroundSprite mountains = new BackgroundSprite();
                mountains.SetTexture("graphics\\background\\mountains_tiled");
                mountains.position.X = primary_camera.viewPort.X / 2 + mountains.texture.Width * i;
                mountains.position.Y = primary_camera.viewPort.Y / 2;
                mountains.parallex += 0.0000001f;
                backgroundLayer.Add(mountains);
            }*/
            snowTile = GraphicsHelper.LoadTexture("graphics\\background\\snow");
            //for (int i = 0; i < 20; i++)
            //{
            //    BackgroundSprite snow = new BackgroundSprite();
            //    snow.parallex = 1;
            //    snow.SetTexture("graphics\\background\\snow");
            //    snow.position.Y = 480 - snow.texture.Height / 2;
            //    snow.position.X = snow.texture.Width / 2 + snow.texture.Width * i;
            //    backgroundLayer.Add(snow);
            //}
            LoadSlope(4);
        }

        private void LoadSlope(int length)
        {

            int marker = 0;
            BackgroundSprite bs = new BackgroundSprite();
            bs.parallex = 1;
            bs.SetTexture("graphics\\objects\\slope-beginning");
            bs.position.X = bs.texture.Width / 2;
            bs.position.Y = 480 - bs.texture.Height / 2;
            objectLayer.Add(bs);

            marker += bs.texture.Width;

            for (int i = 0; i < length; i++)
            {
                bs = new BackgroundSprite();
                bs.parallex = 1;
                bs.SetTexture("graphics\\objects\\slope-centertile");
                bs.position.X = marker + bs.texture.Width / 2;
                bs.position.Y = 480 - bs.texture.Height / 2;
                objectLayer.Add(bs);
                marker += bs.texture.Width;
            }
            bs = new BackgroundSprite();
            bs.parallex = 1;
            bs.SetTexture("graphics\\objects\\slope-end");
            bs.position.X = marker + bs.texture.Width / 2;
            bs.position.Y = 480 - bs.texture.Height / 2;
            objectLayer.Add(bs);
        }



        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed && inMenu == true)
                this.Exit();
            else if(GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            {
                inMenu = true;
                inGame = false;
                SoundHelper.PlayMusic("sounds/clip7");
            }

            Random rand = new Random();

            if (player.position.X > distance_travelled)
            {
                float change = (player.position.X-280) - distance_travelled;
                change = Math.Max(0, change);
                score += (int)change;
                distance_travelled += change;
            }


            if (jumpOver)
            {
                endMenuVisible = true;
            }
            else
            {
                endMenuVisible = false;
            }

            TouchCollection tc = TouchPanel.GetState();

#if WINDOWS_PHONE
            if (timeTillNextTrick <= 0 && !vibration)
            {
                vibration = true;
                TimeSpan ts = new TimeSpan(0,0,0,0,400);
                Microsoft.Devices.VibrateController.Default.Start(ts);
            }
#endif

            //You missed the tap
            if (timeTillNextTrick <= 0 && timeTillNextTrick < difficulty && timeToShowFail < 1000)
            {
                timeToShowFail = 1000;
                timeTillNextTrick = rand.Next(0, 10) * 10 + 2000;
                vibration = false;
                trickErrors++;
            }

            if (timeToShowFail > 0)
                timeToShowFail -= (float)gameTime.ElapsedGameTime.TotalMilliseconds;
            if (timeToShowEarly > 0)            
                timeToShowEarly -= (float)gameTime.ElapsedGameTime.TotalMilliseconds;
            
#if WINDOWS_PHONE
            foreach (TouchLocation tl in tc)
            {
                if (tl.State == TouchLocationState.Pressed)
                {
#else
            do
            {
                MouseState ms = Mouse.GetState();
                bool leftDown = ms.LeftButton == ButtonState.Pressed
                    && prevMouseState.LeftButton != ButtonState.Pressed;

                if (leftDown)
                {
                    int i = 5 + 2;
                }
                prevMouseState = ms;
                if (leftDown && ms.X > 0 && ms.X < Window.ClientBounds.Width && ms.Y > 0 && ms.Y < Window.ClientBounds.Height)
                {
#endif
                    if (jumpOver)
                    {
                        // Reset the jump
                        Reset();
                        break;
                    }
                    if (inMenu == true)
                    {
                        inMenu = false;
                        inGame = true;
                        SoundHelper.PlayMusic("sounds/samutunnari0");
                        break;
                    }
                    else if (gameReady)
                    {
                        //You tapped too early
                        if (timeTillNextTrick > 0 && player.launched)
                        {
                            timeToShowEarly = 800;
                            timeTillNextTrick = rand.Next(0, 20) * 10 + 2000;
                            SoundHelper.PlaySound("sounds\\booing");
                            trickErrors++;
                            //angleBonus = (float)Math.PI / 7;
                        }
                        else if (timeTillNextTrick <= 0 && timeTillNextTrick > difficulty && player.position.Y < 400)
                        {
                            if (nextTapCount > 0)
                            {
                                nextTapCount--;
                            }
                            if (nextTapCount == 0)
                            {
                                if (successfulTricks % 4 == 0)
                                    SoundHelper.PlaySound("sounds\\fanfare");
                                else
                                    SoundHelper.PlaySound("sounds\\applause");
                                player.DoTrick();
                                successfulTricks++;
                                lastScoreGained = (int)((2000 + (int)timeTillNextTrick * 2) + (1000 + (float)difficulty) * 12.0f + (Math.Pow(successfulTricks, 2) * 100));

                                timeTillNextTrick = rand.Next(0, 20) * 50 + 2000 - Math.Min(1000, successfulTricks * 10);
                                switch (successfulTricks)
                                {
                                    case 0:
                                    case 1:
                                        nextTapCount = 1;
                                        break;
                                    case 2:
                                    case 3:
                                        nextTapCount = 2;
                                        break;
                                    case 4:
                                    case 5:
                                        nextTapCount = rand.Next(2, 4);
                                        break;
                                    case 6:
                                    case 7:
                                        nextTapCount = rand.Next(3, 5);
                                        break;
                                    case 8:
                                    case 9:
                                        nextTapCount = rand.Next(4, 6);
                                        break;
                                    case 10:
                                    case 11:
                                        nextTapCount = rand.Next(4, 7);
                                        break;
                                    default:
                                        nextTapCount = rand.Next(5, 8);
                                        break;
                                }
                                //difficulty *= 0.8f;
                                timeToShowScore = 1500;
                                score += lastScoreGained;
                                angleBonus = -(float)Math.PI / (7.1f - (float)Math.Min(2.6, successfulTricks/10.0f) + (trickErrors/4.0f));
                                vibration = false;
#if WINDOWS_PHONE
                                Microsoft.Devices.VibrateController.Default.Stop();
#endif
                            }
                        }
                        if (player.StartRockets())
                        {
                            //save how many game this user has played
                            gamePlayed++;
                            Score gameplayedscore = new Score();
                            gameplayedscore.Points = gamePlayed;
                            gameplayedscore.Data = hiscore.ToString() + "." + GetDeviceModel();
                            gameplayedscore.UserName = mogade.GetUniqueIdentifier().Substring(0, 8);
                            mogade.SaveScore("4f3e4918563d8a3373000053", gameplayedscore, ScoreResponseHandler);
                        }
                    }
                    else
                    {
                        // Tap to retry back to startup position
                        gameReady = true;
                    }
                }
            }
#if WINDOWS
            while (false);
#endif
            
            if (inMenu == true)
                mainMenu.update(gameTime);
            else if (inGame == true)
            {
                UpdateGame(gameTime);
            }

            base.Update(gameTime);
        }

        private void Reset()
        {
            player.dustFrame = 0;
            player.maxSpeed = 1500;
            player.velocity = Vector2.Zero;
            successfulTricks = 0;

            nextTapCount = 1;
            distance_travelled = 0;

            timeTillNextTrick = 2500f;
            difficulty = -1000;   //time to tap
            timeToShowScore = 0f;
            lastScoreGained = 0;
            angleBonus = 0;

            score = 0;
            trickErrors = 0;

            player.launched = false;
            player.exploded = false;
            player.crashed = false;

            player.position = new Vector2(280, 350);
            player.rotation = 0;
            primary_camera.Position = new Vector2(400, 240);
            primary_camera.viewPort.X = 800;
            primary_camera.viewPort.Y = 480;

            gameReady = true;
            jumpOver = false;

            SoundHelper.PlayMusic("sounds\\samutunnari0");

            fanfarePlayed = false;
        }

        private void UpdateGame(GameTime gameTime)
        {
            if (gameTime.ElapsedGameTime.TotalMilliseconds < 1)
            {
                counter++;
            }

            if(player.velocity.Y + random.Next(-20, 21) < 0)
                snowEmitter.EmitterLocation = new Vector2(400, -10);
            else
                snowEmitter.EmitterLocation = new Vector2(400, 490);
            snowEmitter.Update();
            
            if (timeToShowScore > 0)
                timeToShowScore -= (float)gameTime.ElapsedGameTime.TotalMilliseconds;
            if(player.launched && player.position.Y < 400)
            {
                timeTillNextTrick -= (float)gameTime.ElapsedGameTime.TotalMilliseconds;
            }
            if (angleBonus < 0)
            {
                float change = -(float)(Math.PI / 6) * (float)gameTime.ElapsedGameTime.TotalSeconds*2;
                change = Math.Max(change, angleBonus);
                angleBonus -= change;
                angleBonus = Math.Min(angleBonus, 0);
                float overflow = (-(float)Math.PI / 2 + 0.1f) - (GraphicsHelper.GetAngle(player.velocity) + change); //-1.57 - (1.6)
                if (overflow > 0)
                {
                    change += overflow;
                    angleBonus = 0;
                }
                player.velocity = GraphicsHelper.InterpolateVector(player.velocity, change);
            }
            //else if (angleBonus > 0)
            //{                
            //    float change = (float)(Math.PI / 6) * (float)gameTime.ElapsedGameTime.TotalSeconds*2;
            //    change = Math.Max(change, angleBonus);
            //    angleBonus += change;
            //    angleBonus = Math.Max(angleBonus, 0);
            //    player.velocity = GraphicsHelper.InterpolateVector(player.velocity, change);
            //}
            player.Update((float)gameTime.ElapsedGameTime.TotalSeconds);
            primary_camera.Position = player.position;
            player.UpdateRockets((float) gameTime.ElapsedGameTime.TotalSeconds, primary_camera);
        }

        private void UpdateMenu(GameTime gameTime)
        {
            
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);

            GraphicsHelper.EndBatch();

            //particleEngine.Draw(spriteBatch);
            if (inGame == true)
            {
                DrawBackground();
                GraphicsHelper.BeginBatch();
                GraphicsHelper.DrawParticleEmitter(snowEmitter);
                DrawGameObjects();

                base.Draw(gameTime);

                player.Draw(primary_camera);
                spriteBatch.DrawString(uiFont, "SCORE: " + score, new Vector2(2,2), Color.Black);
                spriteBatch.DrawString(uiFont, "SCORE: " + score, Vector2.Zero, Color.White);
                //spriteBatch.DrawString(uiFont, "X: " + primary_camera.Position.X + " Y: " + primary_camera.Position.Y, new Vector2(0,50), Color.White);

                if (timeToShowScore > 0)
                {
                    GraphicsHelper.DrawStringCentered(uiFont, player.TrickName, 35, Color.White);
                    Texture2D tex = successsign;
                    if (successfulTricks % 4 == 0)
                        tex = facesign;

                    float tempHeight = tex.Height;
                    float yScores = tempHeight - tempHeight * timeToShowScore / 1000.0f;
                    if (yScores < tempHeight/4)
                        yScores = yScores*4;
                    else if (yScores < tempHeight - tempHeight/4)
                        yScores = tempHeight;
                    else
                        yScores = tempHeight +(tempHeight * 0.75f - yScores) * 4;
                    GraphicsHelper.Draw(tex, new Vector2(200, 480 + tempHeight / 2 - yScores), 1, 0);
                    GraphicsHelper.Draw(tex, new Vector2(400, 480 + tempHeight / 2 - yScores), 1, 0);
                    GraphicsHelper.Draw(tex, new Vector2(600, 480 + tempHeight / 2 - yScores), 1, 0);
                }
                if (timeToShowFail > 0)
                {
                    GraphicsHelper.Draw(textBox, new Vector2(400, 400), 1, 0);
                    GraphicsHelper.DrawStringCentered(uiFontLarge, "TOO LATE", 350, Color.Black);
                    GraphicsHelper.DrawStringCentered(uiFontLarge, "#%&$@!", 400, Color.Black);
                    GraphicsHelper.Draw(sammydude, new Vector2(800 - sammydude.Width, 480 - sammydude.Height), 1, 0);
                    vibration = false;
                    nextTapCount = 1;
                    successfulTricks = 2;
                }
                else if (timeToShowEarly > 0)
                {
                    GraphicsHelper.Draw(textBox, new Vector2(400, 400), 1, 0);
                    GraphicsHelper.DrawStringCentered(uiFontLarge, "NO TAPPIN'", 350, Color.Black);
                    GraphicsHelper.DrawStringCentered(uiFontLarge, "TILL I SAY SO", 400, Color.Black);
                    GraphicsHelper.Draw(sammydude, new Vector2(800 - sammydude.Width, 480 - sammydude.Height), 1, 0);
                    nextTapCount = 1;
                    successfulTricks = 2;
                }
                else if (!player.launched)
                {
                    GraphicsHelper.DrawStringCentered(uiFontLarge, "TAP TO", 150, Color.White);
                    GraphicsHelper.DrawStringCentered(uiFontLarge, "LAUNCH", 200, Color.White);
                    //GraphicsHelper.Draw(sammydude, new Vector2(800 - sammydude.Width, 480 - sammydude.Height), 1, 0);
                }

                if (timeTillNextTrick < 0 && player.position.Y < 400 && timeTillNextTrick > difficulty && nextTapCount > 0)
                {
                    List<StringBuilder> rows = new List<StringBuilder>();
                    StringBuilder sb = new StringBuilder();
                    for (int i = 0; i < nextTapCount; i++)
                    {
                        if (i % 4 == 0 && i != 0)
                        {
                            rows.Add(sb);
                            sb = null;
                        }
                        if(sb == null)
                            sb = new StringBuilder();
                        sb.Append("TAP! ");

                    }
                    if (sb != null)
                        rows.Add(sb);
                    for (int i = 0; i < rows.Count; i++)
                    {
                        GraphicsHelper.DrawStringCentered(uiFontLarge, rows[i].ToString(), 350 + i*50, Color.White);
                    }
                    //if (nextTapCount > 1)
                    //    GraphicsHelper.DrawStringCentered(uiFontLarge, nextTapCount + "TIMES", 400, Color.White);
                    //else
                    //    GraphicsHelper.DrawStringCentered(uiFontLarge, "TO DO A STUNT", 400, Color.White);
                }

                if (endMenuVisible)
                {
                    DrawEndMenu(gameTime);
                }
            }
            else if (inMenu == true)
            {
                mainMenu.draw(spriteBatch);
            }
            GraphicsHelper.EndBatch();
        }

        private void DrawBackground()
        {
            GraphicsHelper.Draw(bg, new Vector2(primary_camera.viewPort.X/2, Math.Min(bg.Height/2, 280 - primary_camera.Position.Y / 100.0f)), 1, 0);
            //foreach (Sprite s in backgroundLayer)
            //{
            //    s.Draw(primary_camera);
            //}
            int i = (int)(primary_camera.Position.X - primary_camera.viewPort.X) / mountain.Width / 8;
            float mountainLoc = i * mountain.Width - (primary_camera.Position.X /8 - primary_camera.viewPort.X);
            float mountainY = 480 - mountain.Height / 2 - primary_camera.Position.Y / 20.0f;
            GraphicsHelper.Draw(mountain, new Vector2(mountainLoc - mountain.Width, mountainY), 1, 0);
            GraphicsHelper.Draw(mountain, new Vector2(mountainLoc, mountainY), 1, 0);
            GraphicsHelper.Draw(mountain, new Vector2(mountainLoc + mountain.Width, mountainY), 1, 0);
            GraphicsHelper.Draw(mountain, new Vector2(mountainLoc + mountain.Width * 2, mountainY), 1, 0);
            GraphicsHelper.Draw(sun, new Vector2(700 - primary_camera.Position.X / 200.0f, 0 - primary_camera.Position.Y / 200.0f), 1, 0);
            GraphicsHelper.Draw(galaxy1, new Vector2(700, -150 - primary_camera.Position.Y / 500.0f), 1, 0);
            GraphicsHelper.Draw(galaxy2, new Vector2(200, -300 - primary_camera.Position.Y / 600.0f), 1, 0);
            GraphicsHelper.Draw(moon, new Vector2(400 - primary_camera.Position.X / 150.0f, -125 - primary_camera.Position.Y / 150.0f), 1, 0);
            GraphicsHelper.Draw(asteroid01, new Vector2(2200 - primary_camera.Position.X / 50.0f, -125 - primary_camera.Position.Y / 150.0f), 1, 0);
            GraphicsHelper.Draw(asteroid02, new Vector2(2500 - primary_camera.Position.X / 50.0f, -165 - primary_camera.Position.Y / 150.0f), 1, 0);
            GraphicsHelper.Draw(asteroid02, new Vector2(1500 - primary_camera.Position.X / 50.0f, -165 - primary_camera.Position.Y / 150.0f), 1, 0);
            GraphicsHelper.Draw(asteroid03, new Vector2(2600 - primary_camera.Position.X / 50.0f, -135 - primary_camera.Position.Y / 150.0f), 1, 0);
            GraphicsHelper.Draw(asteroid01, new Vector2(3000 - primary_camera.Position.X / 50.0f, -165 - primary_camera.Position.Y / 150.0f), 1, 0);
            GraphicsHelper.Draw(asteroid01, new Vector2(4000 - primary_camera.Position.X / 50.0f, -165 - primary_camera.Position.Y / 150.0f), 1, 0);
            GraphicsHelper.Draw(asteroid01, new Vector2(5000 - primary_camera.Position.X / 50.0f, -165 - primary_camera.Position.Y / 150.0f), 1, 0);
            GraphicsHelper.Draw(asteroid02, new Vector2(2900 - primary_camera.Position.X / 50.0f, -125 - primary_camera.Position.Y / 150.0f), 1, 0);
            GraphicsHelper.Draw(asteroid03, new Vector2(2700 - primary_camera.Position.X / 50.0f, -145 - primary_camera.Position.Y / 150.0f), 1, 0);
            GraphicsHelper.Draw(asteroid03, new Vector2(1700 - primary_camera.Position.X / 50.0f, -145 - primary_camera.Position.Y / 150.0f), 1, 0);

            foreach (BackgroundSprite s in backgroundLayer)
            {
                GraphicsHelper.Draw(s.texture, new Vector2(s.position.X - primary_camera.Position.X / s.parallex, s.position.Y - primary_camera.Position.Y / s.parallex), 1, 0);
            
            }


            //Draw ground, endlessly
            int d = (int)(primary_camera.Position.X - primary_camera.viewPort.X) / snowTile.Width;
            float tileLoc = d * snowTile.Width - (primary_camera.Position.X - primary_camera.viewPort.X);

            while (tileLoc <= primary_camera.viewPort.X + snowTile.Width)
            {
                GraphicsHelper.Draw(snowTile, new Vector2(tileLoc - snowTile.Width, (0 - (primary_camera.Position.Y - primary_camera.viewPort.Y * 1.5f)) - snowTile.Height / 2), 1, 0);
                GraphicsHelper.Draw(snowTile, new Vector2(tileLoc, (0 - (primary_camera.Position.Y - primary_camera.viewPort.Y * 1.5f)) - snowTile.Height / 2), 1, 0);
                tileLoc += snowTile.Width;
            }
                    
            GraphicsHelper.Draw(tree, new Vector2(tileLoc - 575, (0 - (primary_camera.Position.Y - primary_camera.viewPort.Y * 1.4f) - 30) - tree.Height / 2), 1, 0);

            //Don't show behind the slope 
            if (primary_camera.Position.X > 1200)
            {
                GraphicsHelper.Draw(tree, new Vector2(tileLoc - 900, (0 - (primary_camera.Position.Y - primary_camera.viewPort.Y * 1.4f) - 20) - tree.Height / 2), 1, 0);
                GraphicsHelper.Draw(tree, new Vector2(tileLoc - 1300, (0 - (primary_camera.Position.Y - primary_camera.viewPort.Y * 1.45f) - 10) - tree.Height / 2), 1, 0);
            }

            /*
            for (int i = 0; i < 20; i++)
            {
                BackgroundSprite snow = new BackgroundSprite();
                snow.parallex = 1;
                snow.SetTexture("graphics\\background\\snow");
                snow.position.Y = 480 - snow.texture.Height / 2;
                snow.position.X = snow.texture.Width / 2 + snow.texture.Width * i;
                backgroundLayer.Add(snow);*/
            
        }

        private void DrawGameObjects()
        {
            foreach (Sprite s in objectLayer)
            {
                s.Draw(primary_camera);
            }
        }

        private void DrawEndMenu(GameTime gameTime)
        {
            totalElapsedEnd += (float)gameTime.ElapsedGameTime.TotalSeconds;

            if (!fanfarePlayed && player.exploded && totalElapsedEnd > 1.0f)
            {
                SoundHelper.PlaySound("sounds\\finished");
                fanfarePlayed = true;
                mogade.GetLeaderboard("4f3e2ad4563d8a2c6e000024", LeaderboardScope.Overall, 1, GetLeaderBoardScore);
            }

            if (totalElapsedEnd < 10)
            {
                GraphicsHelper.DrawStringCentered(uiFontLarge, "CONGRATULATIONS!", primary_camera.viewPort.Y / 2 - 50, Color.White);
                GraphicsHelper.DrawStringCentered(uiFont, "FINAL JUDGMENT:", primary_camera.viewPort.Y / 2, Color.White);

                string finalText = "no rank";
                if(score < 50000)
                    switch(score%13)
                    {
                        case 0:
                            finalText = "Man, Seriously?";
                            break;
                        case 1:
                            finalText = "Meh";
                            break;
                        case 2:
                            finalText = "Rough Rocketeer";
                            break;
                        case 3:
                            finalText = "VERY Low Rider";
                            break;
                        case 4:
                            finalText = "Minor Tom";
                            break;
                        case 5:
                            finalText = "Homemade Quality";
                            break;
                        case 6:
                            finalText = "Test Pilot";
                            break;
                        case 7:
                            finalText = "Far From Subtle";
                            break;
                        case 8:
                            finalText = "Terminal Velocity Trainee";
                            break;
                        case 9:
                            finalText = "Shabby";
                            break;
                        case 10:
                            finalText = "Soaring Chicken";
                            break;
                        case 11:
                            finalText = "Almost Made It, Almost";
                            break;
                        case 12:
                            finalText = "Radically Ridiculous";
                            break;
                    }
                else if (score < 200000)
                    switch (score%7)
                    {
                        case 0:
                            finalText = "Still Hope For You";
                            break;
                        case 1:
                            finalText = "Skykisser";
                            break;
                        case 2:
                            finalText = "Better Than Icarus";
                            break;
                        case 3:
                            finalText = "Justifiably Abnormal";
                            break;
                        case 4:
                            finalText = "Not Shabby";
                            break;
                        case 5:
                            finalText = "Soaring Eagle";
                            break;
                        case 6:
                            finalText = "Lubed Lightnin'";
                            break;
                    }
                else if (score < 350000)
                    switch (score%7)
                    {
                        case 0:
                            finalText = "Afronaut ";
                            break;
                        case 1:
                            finalText = "Rocket Jockey";
                            break;
                        case 2:
                            finalText = "Reindeers For Breakfast ";
                            break;
                        case 3:
                            finalText = "Hot Dog";
                            break;
                        case 4:
                            finalText = "Nasa Material";
                            break;
                        case 5:
                            finalText = "Turbo Traveller";
                            break;
                        case 6:
                            finalText = "Moonhopper";
                            break;
                    }
                else //if (score < 350000)
                    switch (score%5)
                    {
                        case 0:
                            finalText = "One Serious Mothalova";
                            break;
                        case 1:
                            finalText = "Major Tom";
                            break;
                        case 2:
                            finalText = "Santa II";
                            break;
                        case 3:
                            finalText = "Hank";
                            break;
                        case 4:
                            finalText = "Silver Surfer";
                            break;
                    }
                GraphicsHelper.DrawStringCentered(uiFont, finalText, primary_camera.viewPort.Y / 2 + 25, Color.White);


                if (score > hiscore)
                {
                    hiscore = score;
                    save();
                    Score mogadescore = new Score();
                    mogadescore.Points = hiscore;
                    mogadescore.Data = GetDeviceModel();
                    rankText = "Rank: Loading";
                    mogadescore.UserName = mogade.GetUniqueIdentifier().Substring(0, 8);
                    mogade.SaveScore("4f3e2ad4563d8a2c6e000024", mogadescore, ScoreResponseHandler);
                    
                }
                else
                {
                    GraphicsHelper.DrawStringCentered(uiFont, "YOUR SCORE: " + score, primary_camera.viewPort.Y / 2 + 75, Color.White);
                    GraphicsHelper.DrawStringCentered(uiFont, "YOUR HISCORE: " + hiscore + " " + rankText, primary_camera.viewPort.Y / 2 + 100, Color.White);
                    GraphicsHelper.DrawStringCentered(uiFont, "ONLINE HISCORE: " + onlineHighScore, primary_camera.viewPort.Y / 2 + 125, Color.White);
                }
            }
            else if (totalElapsedEnd > 10 && totalElapsedEnd < 20)
            {
                for(int i= 0; i < 2; i++)
                {
                    Color col = Color.Black;
                    Vector2 v = new Vector2(2, 2);
                    if (i == 1)
                    {
                        col = Color.White;
                        v = Vector2.Zero;
                    }
                    spriteBatch.DrawString(uiFont, "CREDITS", new Vector2(50, primary_camera.viewPort.Y / 2 - 205) + v, col);
                    spriteBatch.DrawString(uiFont, "GAME DESIGN", new Vector2(50, primary_camera.viewPort.Y / 2 - 175) + v, col);
                    spriteBatch.DrawString(uiFont, "KIMO BOISSONNIER", new Vector2(70, primary_camera.viewPort.Y / 2 - 150) + v, col);
                    spriteBatch.DrawString(uiFont, "KAROLIINA KORPPOO", new Vector2(70, primary_camera.viewPort.Y / 2 - 125) + v, col);
                    spriteBatch.DrawString(uiFont, "PROGRAMMING", new Vector2(50, primary_camera.viewPort.Y / 2 - 100) + v, col);
                    spriteBatch.DrawString(uiFont, "KIMO BOISSONNIER", new Vector2(70, primary_camera.viewPort.Y / 2 - 75) + v, col);
                    spriteBatch.DrawString(uiFont, "OLLI ALATALO", new Vector2(70, primary_camera.viewPort.Y / 2 - 50) + v, col);
                    spriteBatch.DrawString(uiFont, "TIMO KORISEVA", new Vector2(70, primary_camera.viewPort.Y / 2 - 25) + v, col);
                    spriteBatch.DrawString(uiFont, "MUSIC & SOUND", new Vector2(50, primary_camera.viewPort.Y / 2 - 0) + v, col);
                    spriteBatch.DrawString(uiFont, "KIMO BOISSONNIER", new Vector2(70, primary_camera.viewPort.Y / 2 + 25) + v, col);
                    spriteBatch.DrawString(uiFont, "JUHO KORHONEN", new Vector2(70, primary_camera.viewPort.Y / 2 + 50) + v, col);
                    spriteBatch.DrawString(uiFont, "ART", new Vector2(50, primary_camera.viewPort.Y / 2 + 75) + v, col);
                    spriteBatch.DrawString(uiFont, "KAROLIINA KORPPOO", new Vector2(70, primary_camera.viewPort.Y / 2 + 100) + v, col);
                    spriteBatch.DrawString(uiFont, "JUHO KORHONEN", new Vector2(70, primary_camera.viewPort.Y / 2 + 125) + v, col);
                    spriteBatch.DrawString(uiFont, "MADE AT FINNISH GAME JAM 2012", new Vector2(50, primary_camera.viewPort.Y / 2 + 155) + v, col);
                }
            }
            else
            {
                totalElapsedEnd = 0;
            }
        }

        private void DrawUI()
        {
            spriteBatch.Begin();

            spriteBatch.End();
        }

        static void save()
        {
#if WINDOWS_PHONE
            IsolatedStorageFile savegameStorage = IsolatedStorageFile.GetUserStoreForApplication();

            // open isolated storage, and write to the file.
            IsolatedStorageFileStream fs = null;
            using (fs = savegameStorage.CreateFile("save"))
            {
                if (fs != null)
                {
                    // just overwrite the existing info for this example.
                    byte[] bytes = System.BitConverter.GetBytes(score);
                    fs.Write(bytes, 0, bytes.Length);
                    bytes = System.BitConverter.GetBytes(hiscore);
                    fs.Write(bytes, 0, bytes.Length);
                    bytes = System.BitConverter.GetBytes(gamePlayed);
                    fs.Write(bytes, 0, bytes.Length);
                }
            }
#else
            string mydocpath =
            Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);           
            using (StreamWriter outfile = new StreamWriter(mydocpath + @"\supersledding.dat"))
            {
                outfile.Write(hiscore.ToString());
                outfile.Flush();
                outfile.Close();
            }
#endif
        }

        void load()
        {
#if WINDOWS_PHONE
            using (IsolatedStorageFile savegameStorage =
                IsolatedStorageFile.GetUserStoreForApplication())
            {

                if (savegameStorage.FileExists("save"))
                {
                    using (IsolatedStorageFileStream fs =
                        savegameStorage.OpenFile("save", System.IO.FileMode.Open))
                    {
                        if (fs != null)
                        {
                            // Reload the saved high-score data.
                            byte[] saveBytes = new byte[4];
                            int count = fs.Read(saveBytes, 0, 4);
                            if (count > 0)
                            {
                                hiscore = System.BitConverter.ToInt32(saveBytes, 0);
                            }
                            count = fs.Read(saveBytes, 0, 4);
                            if (count > 0)
                            {
                                hiscore = System.BitConverter.ToInt32(saveBytes, 0);
                            }
                            count = fs.Read(saveBytes, 0, 4);
                            if (count > 0)
                            {
                                gamePlayed = System.BitConverter.ToInt32(saveBytes, 0);
                            }
                        }
                    }
                }
            }
#else
            
            string mydocpath =
            Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            if(File.Exists(mydocpath + @"\supersledding.dat") == false)
            {
                FileStream fs = File.Create(mydocpath + @"\supersledding.dat");
                fs.Flush();
                fs.Close();
            }
            using (StreamReader sr = new StreamReader(mydocpath + @"\supersledding.dat"))
            {
                try
                {
                    String str = sr.ReadLine();
                    if(String.IsNullOrEmpty(str) == false)
                        hiscore = int.Parse(str);
                }
                catch (Exception ex)
                { }
            }
#endif
        }

        private static void ScoreResponseHandler(Response<SavedScore> r)
        {
            if (!r.Success)
            {
                if (Guide.IsVisible == false)
                {
                    Guide.BeginShowMessageBox("Error", "Network error A",
                        new string[] { "OK" }, 0, MessageBoxIcon.Error, null, null);
                    return;
                }
            }
            else
            {
                rankText = string.Format(" Rank: {0}", r.Data.Ranks.Overall);
            }
        }

        private static void ScoreResponseHandler(Response<Score> r)
        {
            if (!r.Success)
            {
                if (Guide.IsVisible == false)
                {
                    Guide.BeginShowMessageBox("Error", "Network error B",
                        new string[] { "OK" }, 0, MessageBoxIcon.Error, null, null);
                    return;
                }
            }
            else
            {
                hiscore = r.Data.Points;
                //save();
                mogade.GetRank("4f3e2ad4563d8a2c6e000024", hiscore, LeaderboardScope.Overall, rankResponseHandler);
            }
        }

        private static void rankResponseHandler(Response<int> r)
        {
             rankText = string.Format(" Rank: {0}", r.Data);
        }

        private static void GetLeaderBoardScore(Response<LeaderboardScores> r)
        {
            onlineHighScore = r.Data.Scores[0].Points;
        }

        public static string GetDeviceModel()  
        {  
           string model = null;  
           object theModel = null;  
      
           if (Microsoft.Phone.Info.DeviceExtendedProperties.TryGetValue("DeviceName", out theModel))  
              model = theModel as string;

           return model;
        }  
    }
}
